#include "GraphView.h"
#include "ui_GraphView.h"
#include<QInputDialog>
#include<QDebug>

GraphView::GraphView(QWidget* parent):
    QWidget(parent),
    ui(new Ui::GraphView){
    ui->setupUi(this);
    for(int i=0;i<10000;i++)
        for(int j=0;j<10000;j++)
            adj[i][j]=inf;
}

GraphView::~GraphView(){
    delete ui;
}

void GraphView::paintEvent(QPaintEvent *){
    QPainter painter(this);

    QFont font1("Microsoft YaHei",9);
    QFont font2("Microsoft YaHei",12);

    //painter.drawRect(190,70,1000,700);
    painter.setFont(font1);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setPen(Qt::blue);
    /*for(int i=0;i<EdgeCount;i++){
        painter.drawLine(vertex[edge[i].start],vertex[edge[i].end]);
    }*/
    for(int i=0;i<VertexCount;i++)
        for(int j=0;j<=i;j++)
            if(adj[i][j]!=inf){
                painter.drawLine(vertex[i],vertex[j]);
    }
    painter.setPen(Qt::darkMagenta);
    for(int i=0;i<VertexCount;i++)
        for(int j=0;j<=i;j++)
            if(adj[i][j]!=inf){
                int x,y;
                x=(vertex[i].x()+vertex[j].x())/2;
                y=(vertex[i].y()+vertex[j].y())/2;
                painter.drawText(QPoint(x,y),QString::number(adj[i][j]));
            }
    painter.setPen(Qt::black);
    painter.setBrush(Qt::yellow);
    painter.setFont(font2);
    for(int i=0;i<VertexCount;i++){
        painter.drawEllipse(vertex[i],4,4);
        painter.drawText(QPoint(vertex[i].x(),vertex[i].y()),QString::number(i));
    }
}

bool GraphView::SameVex(QPoint a,QPoint b){
    qreal dis=sqrt(pow((a.x()-b.x()),2)+pow(a.y()-b.y(),2));
    if(dis<=30)return true;
    else return false;
}

void GraphView::DelVex(int i){
    for(int j=i;j<VertexCount;j++){
        vertex[j]=vertex[j+1];
    }
    for(int j=i;j<VertexCount;j++){
        for(int k=0;k<VertexCount;k++){
            adj[j][k]=adj[j+1][k];
        }
    }
    for(int j=i;j<VertexCount;j++){
        for(int k=0;k<VertexCount;k++){
            adj[k][j]=adj[k][j+1];
        }
    }
    VertexCount--;
    /*for(int j=0;j<EdgeCount;j++){
        if(i==edge[j].start||i==edge[j].end){
            for(int k=j;k<EdgeCount;k++)
                edge[k]=edge[k+1];
            EdgeCount--;
            j--;
        }
        else{
            if(edge[j].start>i)edge[i].start--;
            if(edge[j].end>i)edge[i].end--;
        }
    }*/
}

void GraphView::AddVex(QPoint TempPos){
    QPoint vex;
    vex.setX(TempPos.x());
    vex.setY(TempPos.y());
    vertex[VertexCount]=vex;
    VertexCount++;
}

void GraphView::PrintAdj(){
    for(int i=0;i<VertexCount;i++){
        for(int j=0;j<VertexCount;j++)
            qDebug()<<adj[i][j]<<" ";
    }
    qDebug()<<endl;
}

void GraphView::mousePressEvent(QMouseEvent *event){
    if(event->button()==Qt::LeftButton){
        QPoint TempPos=event->pos();
        switch (ButtonState) {
        case 1:
            for(int i=0;i<VertexCount;i++){
                if(SameVex(TempPos,vertex[i])){
                    start=i;
                    S1=i;
                    qDebug()<<"success";
                    break;
                }
            }
            qDebug()<<"Vex1Seled"<<start;
            break;
        case 2:
            for(int i=0;i<VertexCount;i++){
                if(i!=start&&SameVex(TempPos,vertex[i])){
                        end=i;
                        S2=i;
                        break;
                }
            }
            qDebug()<<"Vex2Seled"<<end;
            break;
        case 3:{
            AddVex(TempPos);
            update();
            break;
        }
        case 4:
            for(int i=0;i<VertexCount;i++){
                if(SameVex(TempPos,vertex[i])){
                    DelVex(i);
                    break;
                }
            }
            update();
            break;
        case 5:
        {
            qDebug()<<"1";
            /*Edge NewEdge;
            NewEdge.start=start;
            NewEdge.end=end;
            edge[EdgeCount]=NewEdge;*/
            adj[start][end]=1;
            adj[end][start]=1;
            EdgeCount++;
            qDebug()<<start<<end;
            update();
            break;
        }
        case 6:
        {
            qreal Z=QInputDialog::getDouble(this,"InputZ","Z");
            adj[start][end]=Z;
            adj[end][start]=Z;
            break;
        }
        case 7:
        {
            for(int i=0;i<VertexCount;i++)
                for(int j=0;j<i;j++){
                    if(adj[i][j]==0)
                        for(int k=0;k<VertexCount;k++){
                            if(k==i||k==j)
                                continue;
                            if(adj[j][k]==inf){
                                qDebug()<<"inf";
                            }
                            else if(adj[j][k]==0){
                                adj[i][k]=0;
                                adj[k][i]=0;
                            }
                            else{
                                qreal Z=adj[i][k]*adj[j][k]/(adj[i][k]+adj[j][k]);
                                qDebug()<<Z;
                                adj[i][k]=Z;
                                adj[k][i]=Z;
                            }
                            adj[j][k]=inf;
                            adj[k][j]=inf;
                        }
                }
            int i=0;
            while(i!=VertexCount){
                int j;
                for(j=0;j<VertexCount;j++){
                    if(adj[i][j]!=0&&adj[i][j]!=inf)
                        break;
                }
                if(j==VertexCount){
                    DelVex(i);
                    i=0;
                }
                else i++;
            }
            update();
            break;
        }
        case 8:
        {
            int i=0;
            while(i!=VertexCount){
                int TD=0;
                for(int j=0;j<VertexCount;j++)
                    if(adj[i][j]!=inf)
                        TD++;
                qDebug()<<TD;
                if(TD==2&&i!=start&&i!=end){
                    int V[2];
                    int temp=0;
                    for(int j=0;j<VertexCount;j++){
                        if(adj[i][j]!=inf)
                            V[temp++]=j;
                    }
                    if(adj[V[0]][V[1]]==inf){
                        qreal Z=adj[i][V[0]]+adj[i][V[1]];
                        adj[V[0]][V[1]]=Z;
                        adj[V[1]][V[0]]=Z;
                    }
                    else{
                        qreal Z1=adj[i][V[0]]+adj[i][V[1]];
                        qreal Z2=adj[V[0]][V[1]];
                        qreal Z=Z1*Z2/(Z1+Z2);
                        adj[V[0]][V[1]]=Z;
                        adj[V[1]][V[0]]=Z;
                    }
                    if(i<start)
                        start--;
                    if(i<end)
                        end--;
                    DelVex(i);
                    i=0;
                }
                else i++;
            }
            update();
            break;
        }
        case 10:{
            for(int i=0;i<VertexCount;i++){
                if(SameVex(TempPos,vertex[i])){
                    S3=i;
                    break;
                }
            }
            break;
        }
        case 11:{

        }
        case 9:{
            qreal x=(vertex[S1].x()+vertex[S2].x()+vertex[S3].x())/3;
            qreal y=(vertex[S1].y()+vertex[S2].y()+vertex[S3].y())/3;
            AddVex(QPoint(x,y));
            int Y=VertexCount-1;
            qreal Z1=adj[S1][S2]*adj[S1][S3]/(adj[S1][S2]+adj[S1][S3]+adj[S2][S3]);
            qreal Z2=adj[S2][S1]*adj[S2][S3]/(adj[S1][S2]+adj[S1][S3]+adj[S2][S3]);
            qreal Z3=adj[S3][S1]*adj[S3][S2]/(adj[S1][S2]+adj[S1][S3]+adj[S2][S3]);
            adj[Y][S1]=Z1;
            adj[S1][Y]=Z1;
            adj[Y][S2]=Z2;
            adj[S2][Y]=Z2;
            adj[Y][S3]=Z3;
            adj[S3][Y]=Z3;
            adj[S1][S2]=inf;
            adj[S2][S1]=inf;
            adj[S1][S3]=inf;
            adj[S3][S1]=inf;
            adj[S2][S3]=inf;
            adj[S3][S2]=inf;
            update();
            break;
        }
    }
}
}


void GraphView::on_pushButton_clicked()
{
    ButtonState=3;
}

void GraphView::on_pushButton_2_clicked()
{
    ButtonState=4;
}

void GraphView::on_pushButton_3_clicked()
{
    ButtonState=1;
}

void GraphView::on_pushButton_4_clicked()
{
    ButtonState=2;
}

void GraphView::on_pushButton_5_clicked()
{
    ButtonState=5;
}

void GraphView::on_pushButton_6_clicked()
{
    ButtonState=6;
}

void GraphView::on_pushButton_7_clicked()
{
    ButtonState=7;
}

void GraphView::on_pushButton_8_clicked()
{
    ButtonState=8;
}

void GraphView::on_pushButton_9_clicked()
{
    ButtonState=9;
}

void GraphView::on_pushButton_10_clicked()
{
    ButtonState=10;
}

void GraphView::on_pushButton_11_clicked()
{
    ButtonState=11;
}

void GraphView::on_pushButton_12_clicked()
{
    PrintAdj();
}
